package com.magenta.maxoptra.gis.distancematrix;

import com.magenta.maxoptra.gis.GeographicCoordinates;
import com.magenta.maxoptra.gis.RoutingCoordinate;

import java.io.Serializable;

/**
 * equals() and hashCode() used integer values of latitude and longitude
 *
 * @author Sergey Grachev
 */
public final class DistanceMatrixCoordinate implements Serializable, GeographicCoordinates {

    private static final long serialVersionUID = 7230543106551238833L;

    private final double latitude;
    private final double longitude;
    private final int latitudeInteger;
    private final int longitudeInteger;
    private final boolean needCalculateForward;
    private final boolean needCalculateBackward;

    public DistanceMatrixCoordinate(final double latitude, final double longitude) {
        this.latitude = latitude;
        this.longitude = longitude;
        this.latitudeInteger = RoutingCoordinate.getIntCoord(latitude);
        this.longitudeInteger = RoutingCoordinate.getIntCoord(longitude);
        this.needCalculateForward = true;
        this.needCalculateBackward = true;
    }

    public DistanceMatrixCoordinate(final double latitude, final double longitude, final int latitudeInt, final int longitudeInt) {
        this.latitude = latitude;
        this.longitude = longitude;
        this.latitudeInteger = latitudeInt;
        this.longitudeInteger = longitudeInt;
        this.needCalculateForward = true;
        this.needCalculateBackward = true;
    }

    public DistanceMatrixCoordinate(final double latitude, final double longitude, final int latitudeInt, final int longitudeInt,
                                    final boolean needCalculateForward, final boolean needCalculateBackward) {
        this.latitude = latitude;
        this.longitude = longitude;
        this.latitudeInteger = latitudeInt;
        this.longitudeInteger = longitudeInt;
        this.needCalculateForward = needCalculateForward;
        this.needCalculateBackward = needCalculateBackward;
    }

    public DistanceMatrixCoordinate(final double latitude, final double longitude, final boolean needCalculateForward, final boolean needCalculateBackward) {
        this.latitude = latitude;
        this.longitude = longitude;
        this.latitudeInteger = RoutingCoordinate.getIntCoord(latitude);
        this.longitudeInteger = RoutingCoordinate.getIntCoord(longitude);
        this.needCalculateForward = needCalculateForward;
        this.needCalculateBackward = needCalculateBackward;
    }

    public DistanceMatrixCoordinate newInstance(final double latitude, final double longitude,
                                                final boolean calculateForward, final boolean calculateBackward) {
        return new DistanceMatrixCoordinate(latitude, longitude, calculateForward, calculateBackward);
    }

    @Override
    public double getLatitude() {
        return latitude;
    }

    @Override
    public double getLongitude() {
        return longitude;
    }

    @Override
    public int getLatitudeInteger() {
        return latitudeInteger;
    }

    @Override
    public int getLongitudeInteger() {
        return longitudeInteger;
    }

    public boolean isNeedCalculateForward() {
        return needCalculateForward;
    }

    public boolean isNeedCalculateBackward() {
        return needCalculateBackward;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        DistanceMatrixCoordinate that = (DistanceMatrixCoordinate) o;

        if (latitudeInteger != that.latitudeInteger) return false;
        if (longitudeInteger != that.longitudeInteger) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = latitudeInteger;
        result = 31 * result + longitudeInteger;
        return result;
    }

    @Override
    public String toString() {
        return "DistanceMatrixCoordinate{" +
                "latitude=" + latitude +
                ", longitude=" + longitude +
                ", latitudeInteger=" + latitudeInteger +
                ", longitudeInteger=" + longitudeInteger +
                '}';
    }
}
